try {
	Tests.blah
} catch (e) {
	Tests = {};
}

Tests.PlaylistTests = new Class({
	setup: function () {
		this.playlist = new Playlist();
		assertEquals(0, this.playlist.size);
		assertNull(this.playlist.currentSong);
	},
	
	testAddSong: function () {
		const song1 = 'song1';
		var addSongEventFired = false;
		this.playlist.addEvent('onAddSong', function (songs) {
			addSongEventFired = true;
			assertEquals(1, songs.length);
			assertEquals(song1, songs[0]);
		});
		
		this.playlist.addSong(song1);
		assertEquals(1, this.playlist.size);
		assertEquals(0, this.playlist.currentIndex);
		assertEquals(song1, this.playlist.currentSong);
		assertTrue(addSongEventFired);
	},
	
	testAddSongs: function () {
		const song1 = 'song1';
		const song2 = 'song2';
		var songs = [song1, song2];
		var addSongEventFired = false;
		var currentSongChanged = false;
		this.playlist.addEvent('onAddSong', function (addedSongs) {
			addSongEventFired = true;
			assertTrue('added songs should be song1 and song2', songs.same(addedSongs));
		});
		this.playlist.addEvent('onCurrentSongChanged', function () {
			currentSongChanged = true;
		});
		
		this.playlist.addSongs(songs);
		assertEquals(2, this.playlist.size);
		assertEquals(0, this.playlist.currentIndex);
		assertEquals(song1, this.playlist.currentSong);
		assertTrue('add song event should have fired.', addSongEventFired);
		assertTrue('current song changed event should haved fired.',
			currentSongChanged);

		addSongEventFired = false;
		currentSongChanged = false;
		this.playlist.addSongs(songs);
		assertEquals(4, this.playlist.size);
		assertEquals(0, this.playlist.currentIndex);
		assertEquals(song1, this.playlist.currentSong);
		assertTrue('add song event should have fired.', addSongEventFired);
		assertFalse('current song changed event should not haved fired.', 
			currentSongChanged);
	},
	
	testAddNoSongs: function () {
		var addSongEventFired = false;
		this.playlist.addEvent('onAddSong', function (addedSongs) {
			addSongEventFired = true;
		});
		this.playlist.addSongs([]);
		assertFalse(addSongEventFired);
		assertEquals(0, this.playlist.size);
		assertNull(this.playlist.currentSong);
	},
	
	testPlaylistNavigation: function () {
		const song1 = 'song1';
		const song2 = 'song2';
		const song3 = 'song3';
		var songs = [song1, song2, song3];
		this.playlist.addSongs(songs);
		var currentSongChanged = false;
		this.playlist.addEvent('onCurrentSongChanged', function () {
			currentSongChanged = true;
		});
		assertEquals(3, this.playlist.size);
		assertEquals(0, this.playlist.currentIndex);
		
		songs.each(function (item, index) {
			assertEquals(item, this.playlist.get(index));
			currentSongChanged = false;
			this.playlist.currentIndex = index;
			assertTrue('current should be changed', currentSongChanged);
			assertEquals(item, this.playlist.currentSong);
		}.bind(this));
		this.playlist.currentIndex = 0;
		for (i = 1; i < songs.length; i++) {
			currentSongChanged = false;
			this.playlist.next();
			assertTrue('current should be changed', currentSongChanged);
			assertEquals(this.playlist.get(i), this.playlist.currentSong);
		}
		
		currentSongChanged = false;
		var playlistFinished = false;
		this.playlist.addEvent('onPlaylistFinished', function () {
			playlistFinished = true;
		});
		this.playlist.next();
		assertTrue('playlist finished should be true', playlistFinished);
		assertFalse('current should not have changed yet.', currentSongChanged);
		this.playlist.reset();
		assertTrue('current should have changed.', currentSongChanged);
		
		this.playlist.currentIndex = songs.length - 1;
		for (i = this.playlist.currentIndex; i > 0; i--) {
			currentSongChanged = false;
			this.playlist.prev();
			assertTrue('current should be changed', currentSongChanged);
			assertEquals(this.playlist.get(i-1), this.playlist.currentSong);
		}
		assertEquals(0, this.playlist.currentIndex);
		
		currentSongChanged = false;
		this.playlist.prev();
		assertEquals(0, this.playlist.currentIndex);
		assertFalse(currentSongChanged);
	},
	
	testRemoveSingleSongCurrentNotUpdated: function () {
		const song1 = 'song1';
		const song2 = 'song2';
		const song3 = 'song3';
		const song4 = 'song4';
		const song5 = 'song5';
		var songs = [song1, song2, song3, song4, song5];
		this.playlist.addSongs(songs);
		
		var currentSongChanged = false;
		this.playlist.addEvent('onCurrentSongChanged', function () {
			currentSongChanged = true;
		});
		
		assertEquals(song1, this.playlist.currentSong);
		var removeCalled = false;
		this.playlist.addEvent('onRemoveSong', function (removedSongs) {
			removeCalled = true;
			assertTrue([i].same(removedSongs));
		});
		for (i = songs.length - 1; i > 0; i--) {
			removeCalled = false;
			this.playlist.removeSong(i);
			assertTrue(removeCalled);
			assertFalse(currentSongChanged);
			assertEquals(song1, this.playlist.currentSong);
		}
		
		var i = 0;
		assertEquals(1, this.playlist.size);
		var playlistEmpty = false;
		this.playlist.addEvent('onPlaylistEmpty', function () {
			playlistEmpty = true;
		});
		this.playlist.removeSong(i);
		assertTrue(removeCalled);
		assertTrue(playlistEmpty);
		assertNull(this.playlist.currentSong);
		assertEquals(0, this.playlist.size);
	},
	
	testRemoveMultipleSongsCurrentNotUpdated: function () {
		const song1 = 'song1';
		const song2 = 'song2';
		const song3 = 'song3';
		const song4 = 'song4';
		const song5 = 'song5';
		var songs = [song1, song2, song3, song4, song5];
		this.playlist.addSongs(songs);
		var currentSongChanged = false;
		this.playlist.addEvent('onCurrentSongChanged', function () {
			currentSongChanged = true;
		});
		
		var removed = [2, 3, 4];
		var removeCalled = false;
		this.playlist.addEvent('onRemoveSong', function (removedSongs) {
			removeCalled = true;
			assertEquals(removed.length, removedSongs.length);
			removed.each(function (item) {
				assertContains(item, removedSongs);
			});
		});
		this.playlist.removeSong(removed);
		assertTrue(removeCalled);
		assertFalse(currentSongChanged);
		assertEquals(2, this.playlist.size);
		for (i = 0; i < this.playlist.size; i++) {
			assertEquals(songs[i], this.playlist.get(i));
		}
	}, 
	
	testRemoveSongsWithDuplicateUnorderedAndOutOfRange: function () {
		const song1 = 'song1';
		const song2 = 'song2';
		const song3 = 'song3';
		const song4 = 'song4';
		const song5 = 'song5';
		var songs = [song1, song2, song3, song4, song5];
		this.playlist.addSongs(songs);
		
		this.playlist.currentIndex = 2;
		const currentSong = this.playlist.currentSong;
		this.playlist.removeSong([1,4,3,1,100,-1]);
		assertEquals(2, this.playlist.size);
		assertEquals(song1, this.playlist.get(0));
		assertEquals(song3, this.playlist.get(1));
		assertEquals(currentSong, this.playlist.currentSong);
	}, 
	
	testEmpty: function () {
		var emptyFired = false;
		var removeSongFired = false;
		this.playlist.addEvent('onPlaylistEmpty', function () {
			emptyFired = true;
		}).addEvent('onRemoveSong', function () {
			removeSongFired = true;
		});
		this.playlist.addSongs(['song1']);
		assertNotEquals(0, this.playlist.size);
		assertNotNull(this.playlist.currentSong);
		
		this.playlist.empty();
		assertTrue(emptyFired);
		assertTrue(removeSongFired);
		assertNull(this.playlist.currentSong);
	}
});

// @TODO test ui code